package com.njym.payment.smileDemo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayResponse;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.ZolozAuthenticationCustomerSmilepayInitializeRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.ZolozAuthenticationCustomerSmilepayInitializeResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.njym.entity.PlatformBusinessRec;
import com.njym.entity.SysPaymentMode;
import com.njym.payment.alipay.AliPayProperties;
import com.njym.payment.alipay.GetAliPayClient;
import com.njym.payment.alipay.properties.SmilePayParams;
import com.njym.payment.alipay.properties.TradepayParam;
import com.njym.service.PlatformBusinessRecService;
import com.njym.vo.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author zhy
 * @date 2019-08-02 13:50
 **/
@RestController
@RequestMapping("/alipaySmilePay")
public class MainActivity {
	private static final Logger log = LoggerFactory.getLogger(MainActivity.class);

	@Resource
	private GetAliPayClient getAliPayClient;

	@Resource
	private PlatformBusinessRecService platformBusinessRecService;

	//刷脸支付相关
	private static final String SMILEPAY_CODE_SUCCESS = "10000";

	private static final String SMILEPAY_SUBCODE_LIMIT = "ACQ.PRODUCT_AMOUNT_LIMIT_ERROR";

	private static final String SMILEPAY_SUBCODE_BALANCE_NOT_ENOUGH = "ACQ.BUYER_BALANCE_NOT_ENOUGH";

	private static final String SMILEPAY_SUBCODE_BANKCARD_BALANCE_NOT_ENOUGH = "ACQ.BUYER_BANKCARD_BALANCE_NOT_ENOUGH";

	private static final String SMILEPAY_TXT_LIMIT = "刷脸支付超出限额，请选用其他支付方式";

	private static final String SMILEPAY_TXT_EBALANCE_NOT_ENOUGH = "账户余额不足，支付失败";

	private static final String SMILEPAY_TXT_BANKCARD_BALANCE_NOT_ENOUGH = "账户余额不足，支付失败";

	private static final String SMILEPAY_TXT_FAIL = "抱歉未支付成功，请重新支付";

	private static final String SMILEPAY_TXT_SUCCESS = "刷脸支付成功";

	/**
	 * 设备初始化，订单号初始化
	 * 客户端通过sdk获取到机器的信息后，将信息传到这里来，再传到支付宝获取2个值作为刷脸付的参数。
	 */
	@PostMapping("/init")
	public Json smilePay(@Valid SmilePayParams prepayParams, BindingResult bindingResult) {
		String oper = "smilePayMateInit";
		if (bindingResult.getErrorCount() > 0) {
			return Json.fail(oper, bindingResult.getFieldErrors().get(0).getDefaultMessage());
		}
		SysPaymentMode sysPaymentMode = getAliPayClient.getPaymentModeByOrgId(prepayParams.getOrgId());
		// 初始化数据到数据库
		PlatformBusinessRec businessRec = new PlatformBusinessRec();
		businessRec.setOrgId(prepayParams.getOrgId());
		businessRec.setChannelId(prepayParams.getChannelId());
		businessRec.setModeId(sysPaymentMode.getId());
		businessRec.setRecType(Byte.valueOf("1"));
		businessRec.setOutTradeNo(prepayParams.getOutTradeNo());
		businessRec.setCardNo(prepayParams.getCardNo());
		businessRec.setName(prepayParams.getName());
		BigDecimal bd = new BigDecimal(prepayParams.getTotalAmount());
		//设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
		bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
		businessRec.setTotalFee(bd);
		businessRec.setTradeDate(new Date());
		businessRec.setAccountFlag(Byte.valueOf("0"));
		businessRec.setAbnormalFlag(Byte.valueOf("0"));
		businessRec.setCreateDate(new Date());
		businessRec.setOperatorId(prepayParams.getOperatorId());
		businessRec.setOperatorName(prepayParams.getOperatorName());
		platformBusinessRecService.insert(businessRec);

		String zimId = "";
		String zimInitClientData = "";
		log.info(prepayParams.getMetaInfo());
		//正式接入请上传metaInfo到服务端，不要忘记UrlEncode，使用服务端使用的sdk从服务端访问openapi获取zimId和zimInitClientData；
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(prepayParams.getOrgId());
		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(prepayParams.getOrgId());


		ZolozAuthenticationCustomerSmilepayInitializeRequest request = new ZolozAuthenticationCustomerSmilepayInitializeRequest();

		// zolozGetMetaInfo接口返回的metainfo对象中加入业务参数
		JSONObject zimmetainfo = JSON.parseObject(prepayParams.getMetaInfo());
		JSONObject merchantInfo = zimmetainfo.getJSONObject("merchantInfo");
//		merchantInfo.put("pay_amount", "0.01");//可选，支付币种订单金额,值为double类型
		merchantInfo.put("pay_currency", "CNY");//可选，支付币种，目前仅支持 人民币：CNY

		JSONObject extInfo = new JSONObject();

		/* start: 如果是姓名＋身份证号方式的刷脸支付，请加入以下代码 */
		//必填，当前被认证用户的身份证号
		//		extInfo.put("certNo", "身份证号");
		//必填，当前被认证用户的姓名（保持和身份证一致）
		//		extInfo.put("certName", "身份证姓名");
		//必填，写为IDCARD，表明身份证
		//		extInfo.put("certType", "IDCARD");
		//必填，固定写为8，表明基于姓名和身份证号的刷脸支付场景
		//		extInfo.put("bizType", "8");
		/* end: -------------------------------------------- */

		zimmetainfo.put("extInfo", extInfo);
		request.setBizContent(zimmetainfo.toJSONString());
		try {
			ZolozAuthenticationCustomerSmilepayInitializeResponse zolozResponse = alipayClient.execute(request, "", aliPayProperties.getAppAuthToken());
			log.info(zolozResponse.getResult());
			if (SMILEPAY_CODE_SUCCESS.equals(zolozResponse.getCode())) {

				String result = zolozResponse.getResult();
				JSONObject resultJson = JSON.parseObject(result);
				zimId = resultJson.getString("zimId");
				zimInitClientData = resultJson.getString("zimInitClientData");
				log.info("zimId" + zimId);
				log.info("zimInitClientData" + zimInitClientData);
				//人脸调用
				if (zimId.equals("") || zimInitClientData.equals("")) {
					log.warn("调用失败");
					return Json.fail(oper, "初始化失败，zimId或者zimInitClientData为空");
				}else{
					return Json.succ(oper).data("zimId", zimId).data("zimInitClientData", zimInitClientData);
				}
			}else{
				log.warn("调用失败");
				return Json.fail(oper, "初始化失败，zimId或者zimInitClientData为空");
			}

		}
		catch (AlipayApiException e) {
			e.printStackTrace();
			log.warn("调用失败");
			return Json.fail(oper, "调用失败");
		}
	}


	@PostMapping("/pay")
	public Json pay(String ftoken,String outTradeNo,String orgId) throws Exception {
		String oper = "smilePay";
		Wrapper<PlatformBusinessRec> queryParams = new EntityWrapper<>();
		queryParams.eq("out_trade_no", outTradeNo);
		queryParams.eq("deleted", 0);
		PlatformBusinessRec businessRec = platformBusinessRecService.selectOne(queryParams);
		if (businessRec == null) {
			return Json.fail(oper, "该订单号不存在！");
		}

		AlipayClient alipayClient = getAliPayClient.getClientByOrgId(orgId);
		AliPayProperties aliPayProperties = getAliPayClient.getAliPayPropertiesByOrgId(orgId);
		AlipayTradePayRequest alipayTradePayRequest = new AlipayTradePayRequest();
		TradepayParam tradepayParam = new TradepayParam();
		tradepayParam.setOut_trade_no(outTradeNo);
		//auth_code和scene填写需要注意
		tradepayParam.setAuth_code(ftoken);
		tradepayParam.setScene("security_code");
		tradepayParam.setSubject("刷脸支付");
		tradepayParam.setStore_id("smilepay test");
		tradepayParam.setTimeout_express("5m");
		tradepayParam.setTotal_amount(businessRec.getTotalFee().toString());
		alipayTradePayRequest.setBizContent(JSON.toJSONString(tradepayParam));
		 AlipayResponse response = alipayClient.execute(alipayTradePayRequest, "", aliPayProperties.getAppAuthToken());

		if (response != null && SMILEPAY_CODE_SUCCESS.equals(response.getCode())) { ;
			log.warn(SMILEPAY_TXT_SUCCESS);
			String tradeNo = ((AlipayTradePayResponse)response).getTradeNo();
			// 更新到数据库
			businessRec.setTradeNo(tradeNo);
			businessRec.setTradeDate(new Date());
			businessRec.setTradeStatus("TRADE_SUCCESS");
			platformBusinessRecService.updateById(businessRec);
			return Json.succ(oper).data("tradeNo", tradeNo);
		} else {
			if (response != null) {
				String subCode = response.getSubCode();
				if (SMILEPAY_SUBCODE_LIMIT.equalsIgnoreCase(subCode)) {
					//								promptText(SMILEPAY_TXT_LIMIT);
					log.warn(SMILEPAY_TXT_LIMIT);
					return Json.fail(oper, SMILEPAY_TXT_LIMIT);
				} else if (SMILEPAY_SUBCODE_BALANCE_NOT_ENOUGH.equalsIgnoreCase(subCode)) {
					//								promptText(SMILEPAY_TXT_EBALANCE_NOT_ENOUGH);
					log.warn(SMILEPAY_TXT_EBALANCE_NOT_ENOUGH);
					return Json.fail(oper, SMILEPAY_TXT_EBALANCE_NOT_ENOUGH);
				} else if (SMILEPAY_SUBCODE_BANKCARD_BALANCE_NOT_ENOUGH.equalsIgnoreCase(subCode)) {
					//								promptText(SMILEPAY_TXT_BANKCARD_BALANCE_NOT_ENOUGH);
					log.warn(SMILEPAY_TXT_BANKCARD_BALANCE_NOT_ENOUGH);
					return Json.fail(oper, SMILEPAY_TXT_BANKCARD_BALANCE_NOT_ENOUGH);
				} else {
					//								promptText(SMILEPAY_TXT_FAIL);
					log.warn(SMILEPAY_TXT_FAIL);
					return Json.fail(oper, SMILEPAY_TXT_FAIL);
				}
			} else {
				//							promptText(SMILEPAY_TXT_FAIL);
				log.warn(SMILEPAY_TXT_FAIL);
				return Json.fail(oper, SMILEPAY_TXT_FAIL);
			}
		}

	}

}